﻿#include <QDateTime>
#include <QDir>
#include <QCoreApplication>
#include "HKAIDevice.h"
#include "CGlobal.h"
#include "CModelMng.h"
#include <DbgHelp.h>
#pragma comment(lib, "Dbghelp.lib")
// 通用的异常回调函数模板
long __stdcall CommonCrashInfocallback(_EXCEPTION_POINTERS* pexcp, const QString& driverName)
{
	// 创建驱动专用的崩溃文件文件夹
	QString dumpPath = QCoreApplication::applicationDirPath() + "/DriverErrorDump/";
	QDir dir(dumpPath);
	if (!dir.exists())
	{
		dir.mkpath(".");
	}

	// 文件名包含驱动名称
	QString dumpFileName = dumpPath + driverName + "_" +
		QDateTime::currentDateTime().toString("yyyyMMddhhmmss") + ".dmp";
	std::wstring wstr = dumpFileName.toStdWString();

	// 创建dmp文件
	HANDLE hDumpFile = ::CreateFileW(
		wstr.c_str(),
		GENERIC_WRITE,
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL
	);

	if (hDumpFile != INVALID_HANDLE_VALUE)
	{
		MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
		dumpInfo.ExceptionPointers = pexcp;
		dumpInfo.ThreadId = GetCurrentThreadId();
		dumpInfo.ClientPointers = TRUE;

		::MiniDumpWriteDump(
			GetCurrentProcess(),
			GetCurrentProcessId(),
			hDumpFile,
			MiniDumpNormal,
			&dumpInfo,
			NULL,
			NULL
		);
		CloseHandle(hDumpFile);
	}
	return EXCEPTION_EXECUTE_HANDLER;
}

//异常回调
long __stdcall HKAICallback(_EXCEPTION_POINTERS* pexcp)
{
	return CommonCrashInfocallback(pexcp, "HKAI");
}

// 工厂函数：创建设备实例
IDevice* createDevice(SDeviceConfig* pDevice)
{
	// 只在第一次调用时设置异常处理
	static bool bFirstCall = true;
	if (bFirstCall) 
	{
		::SetUnhandledExceptionFilter(HKAICallback);
		bFirstCall = false;
	}
	CModelMng::instance();
	if (!CModelMng::instance().m_bDbInit)
		return nullptr;
	bool bRet = false;
	HKAIDevice* pDev = new HKAIDevice(pDevice->sDeviceId, pDevice->sDeviceName, bRet);
	if (bRet)
	{
		CModelMng::instance().m_vecDev.push_back(pDev);
		return pDev;
	}
	else
	{
		delete pDev;
		pDev = nullptr;
		return nullptr;
	}
}

DEVICE_EXPORT QVector<IDevice*>* createDevices(SDeviceConfig* pDevice)
{
	CModelMng::instance();
	if (!CModelMng::instance().m_bDbInit)
		return nullptr;
	bool bRet = false;
	QVector<IDevice*>* vecDevice = new QVector<IDevice*>();
	HKAIDevice* pDev = new HKAIDevice(pDevice->sDeviceId, pDevice->sDeviceName, bRet);
	if (bRet)
	{
		CModelMng::instance().m_vecDev.push_back(pDev);
		vecDevice->push_back(pDev);
		return vecDevice;
	}
	else
	{
		delete pDev;
		pDev = nullptr;
		delete vecDevice;
		vecDevice = nullptr;
		return nullptr;
	}
}

// 销毁设备实例
void destroyDevice(IDevice* dev)
{
	delete dev;
	dev = nullptr;
}

QVector<QString>*  getModelList()
{
	static QVector<QString> modelList = { A2T("AI检测摄像头") };
	return &modelList;
}

QVector<QWidget*>*  getPublicCardList()
{
	return CModelMng::instance().getPublicCardList();
}

QWidget* getPublicCard(int nCardId, QString* psCardGuid)
{
	return CModelMng::instance().getPublicCard(nCardId, psCardGuid);
}

HKAIDevice::HKAIDevice(const QString &sDevGuid, const QString &sDevName, bool& bRet)
{
	m_sDevGuid = sDevGuid;
	m_pDeviceConfig = new SDeviceConfig();
	m_pDeviceConfig->sDeviceName = sDevName;
	m_pDeviceConfig->sDeviceId = sDevGuid;
	m_pDevMng = new CHKAIDevMange(sDevGuid, sDevName, bRet);
	if (bRet)
	{
		m_pDevMng->startDev();
	}
}

HKAIDevice::~HKAIDevice()
{
	if (m_pDevMng != nullptr)
	{
		delete m_pDevMng;
		m_pDevMng = nullptr;
	}
}

QObject* HKAIDevice::getDeviceObject()
{
	return nullptr;
}

bool HKAIDevice::startDevice()
{
	if (m_pDevMng != nullptr)
	{
		return m_pDevMng->startDev();
	}
	else
	{
		return false;
	}
}

void HKAIDevice::stopDevice()
{
	if (m_pDevMng != nullptr)
	{
		return m_pDevMng->stopDev();
	}
}

void HKAIDevice::deleteDevice()
{
	QString sDevId = m_sDevGuid;//上层的设备ID
	m_pDevMng->deleteDev(sDevId);
}

bool HKAIDevice::controlDevice(const QString& cmd)
{
	return false;
}

QString HKAIDevice::getDeviceStatus() const
{
	if (m_pDevMng != nullptr)
	{
		return m_pDevMng->getDeviceStatus();
	}
	return "";
}

QList<CMeasurePoint*> HKAIDevice::getMeasurePoints() const
{
	QList<CMeasurePoint*> list;
	if (m_pDevMng != nullptr)
	{
		return m_pDevMng->getMeasurePoints();
	}
	else
	{
		return list;
	}
}

void HKAIDevice::setAlarmArea(const QString& area)
{

}

QList<QString> HKAIDevice::getDeviceLogs() const
{
	QList<QString> listRet;
	return listRet;
}

QWidget* HKAIDevice::getDeviceConfigUi()
{
	if (m_pDevMng != nullptr)
	{
		return m_pDevMng->getConfigWidget();
	}
	else
	{
		return nullptr;
	}
}

QWidget* HKAIDevice::getDeviceRunUi()
{
	if (m_pDevMng != nullptr)
	{
		return m_pDevMng->getDeviceRunUi();
	}
	else
	{
		return nullptr;
	}
}

QWidget* HKAIDevice::getDeviceThumbnailUi(int nId /*= 0*/)
{
	if (m_pDevMng != nullptr)
	{
		return m_pDevMng->createWidget(EWidgetType(nId));
	}
	else
	{
		return nullptr;
	}
}

QVector<QWidget*> HKAIDevice::getDeviceUiList()
{
	QVector<QWidget*> vecRet;
	if (m_pDevMng != nullptr)
	{
		return m_pDevMng->getDeviceUiList();
	}
	else
	{
		return vecRet;
	}
}

QMap<QString, QString> HKAIDevice::getInputPointList()
{
	QMap<QString, QString> mapRet;
	if (m_pDevMng != nullptr)
	{
		return m_pDevMng->getInputPointList();
	}
	return mapRet;
}

void HKAIDevice::setInputPointList(QMap<QString, CMeasurePoint*>vecInputPoint)
{
	if (m_pDevMng != nullptr)
	{
		m_pDevMng->setInputPointList(vecInputPoint);
	}
}
